home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Tool Chest / Development Kits / MPW etc. / Debuggers / SADE / SADE 1.4a3 / SADE Example Scripts / sc7 < prev   
Encoding:
Text File  |  1992-07-10  |  4.1 KB  |  152 lines  |  [TEXT/sade]

  1. ##########################################################################################
  2. #    Symbolic Application Debugging Environment 1.4
  3. #
  4. #    copyright Apple Computer, Inc. 1987-1991
  5. #    All rights reserved.
  6. #
  7. ##########################################################################################
  8.  
  9.  
  10. define __ROMlo__, __ROMhi__            # ROM boundaries
  11. define __heapLo__, __heapHi__        # heap boundaries
  12. define __stackLo__, __stackHi__        # stack boundaries
  13.  
  14.  
  15. # Inits stuff and makes sure stack is OK before we try to crawl it.
  16. func InitSC7()
  17.     __stackLo__ := A7
  18.     __stackHi__ := CurStackBase
  19.     __heapLo__ := ApplZone
  20.     __heapHi__ := ApplLimit
  21.     __ROMlo__ := RomBase & TargetAddrMask
  22.     __ROMhi__ := __ROMlo__ + $40000    # assume 256K ROM- need a better way!!!
  23.     if (__stackLo__ & 1) or (__stackHi__ & 1) then
  24.         return 0
  25.     end
  26.     if (A7 > __stackHi__) then
  27.         return 0
  28.     end
  29.     return 1
  30. end
  31.  
  32. # Returns 1 if addr is in application heap or ROM.
  33. func IsCodeAddr(addr)
  34.     addr := unsignedlong(addr & TargetAddrMask)
  35.     if (addr >= __heapLo__) and (addr <= __heapHi__) then        # in heap
  36.         return 1
  37.     elseif (addr >= __ROMlo__) and (addr <= __ROMhi__) then        # in ROM
  38.         return 1
  39.     end
  40.     return 0
  41. end
  42.  
  43. # Is addr the return address to somewhere?
  44. # This function checks whether the location immediately before
  45. # addr contains a JSR, BSR, or A-trap, and if so returns the
  46. # address of that instruction.  Otherwise it returns 0.
  47. func ReturnAddress(addr)
  48.     define instr, callAddr
  49.     addr := unsignedlong(addr & TargetAddrMask)
  50.     # check if addr is in an executable region
  51.     if not IsCodeAddr(addr) then
  52.         return 0            # not in heap (or ROM)
  53.     end
  54.     callAddr := unsignedlong(addr - 2)
  55.     if not IsCodeAddr(callAddr) then
  56.         return 0
  57.     end
  58.     instr := ^unsignedword(callAddr)^
  59.     if instr = $6100 then
  60.         return callAddr        # BSR with byte displacement
  61.     elseif (instr & $FFF8) = $4E90 then
  62.         return callAddr        # JSR (An)
  63.     elseif (instr & $F000) = $A000 then
  64.         return callAddr        # A-trap
  65.     end
  66.     callAddr := unsignedlong(addr - 4)
  67.     if not IsCodeAddr(callAddr) then
  68.         return 0
  69.     end
  70.     instr := ^unsignedword(callAddr)^
  71.     if instr = $6100 then
  72.         return callAddr        # BSR with word displacement
  73.     elseif (instr & $FFF8) = $4EA8 then
  74.         return callAddr        # JSR (disp, An)
  75.     elseif (instr & $FFF8) = $4EB0 then
  76.         return callAddr        # JSR (disp, An, Dn)
  77.     elseif instr = $4EBA then
  78.         return callAddr        # JSR (disp, PC)
  79.     elseif instr = $4EBB then
  80.         return callAddr        # JSR (disp, PC, Dn)
  81.     elseif instr = $4EB8 then
  82.         return callAddr        # JSR (xxxx).W
  83.     end
  84.     callAddr := unsignedlong(addr - 6)
  85.     if not IsCodeAddr(callAddr) then
  86.         return 0
  87.     end
  88.     instr := ^unsignedword(callAddr)^
  89.     if instr = $4EB9 then
  90.         return callAddr        # JST (xxxx).L
  91.     end
  92.     return 0                # not a return addr
  93. end
  94.  
  95. # Does addr seem to point to an A6 link value?
  96. # We check that addr is even, within the stack boundaries, and between
  97. # the actual A6 and previous A6 values (or, of course, that it actually
  98. # points to the previous A6!).
  99. func A6Link(addr, prevA6)
  100.     if (addr & 1) or (addr < __stackLo__) or (addr > __stackHi__) then
  101.         return 0
  102.     end
  103.     if (^unsignedlong(addr)^ = prevA6) then
  104.         return 1
  105.     end
  106.     if (addr < A6) or (addr < prevA6) then
  107.         return 0
  108.     end
  109.     return 1
  110. end
  111.  
  112. # Try stack addresses from CurStackBase down to current A7.
  113. # For each that looks like a return address, display it and
  114. # check the preceding value to see if it looks like an A6 link.
  115. proc ShowFrame(prevA6, thisA7)
  116.     define name
  117.     define maybeA6loc := thisA7 - 4    # might be an A6 link value here
  118.     define nextA7 := thisA7 - 2        # check on word boundaries
  119.     define callAddr := ReturnAddress(^unsignedlong(thisA7)^)
  120.     if callAddr <> 0 then
  121.         printf "$%.8X     ", long(thisA7)
  122.         if A6Link(maybeA6loc, prevA6) then
  123.             printf "$%.8X     ", long(maybeA6loc)
  124.             prevA6 := maybeA6loc
  125.         else
  126.             printf "              "
  127.         end
  128.         name := where(callAddr)
  129.         if copy(name, 1, 1) = '$' then
  130.             name := ''
  131.         end
  132.         printf "$%.8X  %s\n", long(callAddr), name
  133.     end
  134.     if nextA7 >= A7 then
  135.         ShowFrame(prevA6, nextA7)
  136.     end
  137. end
  138.  
  139. # The main entry point.
  140. proc StackCrawl7
  141.     CheckNullTarget
  142.     if not InitSC7() then
  143.         alert "Damaged stack:\nA7 must be even and <= CurStackBase."
  144.         abort
  145.     end
  146.     printf "Return addresses on the stack\n"
  147.     printf "Stack Addr    Frame Addr    Caller\n"
  148.     ShowFrame(0, CurStackBase - 4)
  149. end
  150.  
  151. macro sc7    'StackCrawl7'
  152.